Skip to content

fix(attachments): cross tenant hardening#5310

Open
icecrasher321 wants to merge 109 commits into
stagingfrom
fix-cross-tenant-file-read
Open

fix(attachments): cross tenant hardening#5310
icecrasher321 wants to merge 109 commits into
stagingfrom
fix-cross-tenant-file-read

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

Closes a cross-tenant file read where an authenticated user could label a private workspace/… key with a world-readable context (og-images/workspace-logos) to bypass verifyFileAccess and read another tenant’s file. resolveFileInputToUrl, downloadFileFromStorage, the provider attachment path, and files/parse now infer context solely from the key prefix via inferContextFromKey.

Type of Change

  • Other: Security

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

waleedlatif1 and others added 30 commits April 3, 2026 23:30
…ership workflow edits via sockets, ui improvements
…ration, signup method feature flags, SSO improvements
* feat(posthog): Add tracking on mothership abort (#4023)

Co-authored-by: Theodore Li <theo@sim.ai>

* fix(login): fix captcha headers for manual login  (#4025)

* fix(signup): fix turnstile key loading

* fix(login): fix captcha header passing

* Catch user already exists, remove login form captcha
…nts, secrets performance, polling refactors, drag resources in mothership
…endar triggers, docs updates, integrations/models pages improvements
…mat, logs performance improvements

fix(csp): add missing analytics domains, remove unsafe-eval, fix workspace CSP gap (#4179)
fix(landing): return 404 for invalid dynamic route slugs (#4182)
improvement(seo): optimize sitemaps, robots.txt, and core web vitals across sim and docs (#4170)
fix(gemini): support structured output with tools on Gemini 3 models (#4184)
feat(brightdata): add Bright Data integration with 8 tools (#4183)
fix(mothership): fix superagent credentials (#4185)
fix(logs): close sidebar when selected log disappears from filtered list; cleanup (#4186)
v0.6.46: mothership streaming fixes, brightdata integration
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 1, 2026 3:50am

Request Review

@cursor

cursor Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Security fix on authorization for file read paths (parse, downloads, provider attachments); incorrect inference would break legitimate access or leave gaps, but the change narrows trust to key structure rather than client metadata.

Overview
Closes a cross-tenant file read where an authenticated user could point at another tenant’s private storage key but supply a world-readable storage context (e.g. og-images, workspace-logos) so verifyFileAccess granted access before download.

Server paths that resolve, download, or presign files now always derive storage context from the key prefix via inferContextFromKey, instead of honoring UserFile.context or other caller-controlled context. That applies to file parse (handleCloudFile), presigned URL / download helpers in file-utils.server.ts, and provider large-file attachments (presign and upload access checks).

Logging no longer distinguishes “explicit” vs “inferred” context because only key-based inference is used.

Reviewed by Cursor Bugbot for commit 3cc2692. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens file attachment context handling across storage reads and provider uploads. The main changes are:

  • Added a trusted context resolver that prefers key prefixes.
  • Preserved non-public context fallback for legacy keys.
  • Updated server utility and provider attachment paths to use the resolver.
  • Added tests for mismatched public contexts and legacy private fallback.

Confidence Score: 4/5

This is close, but the download endpoint should be fixed before merging.

  • The new resolver closes the public-context relabeling path in the updated utility and provider flows.
  • The download endpoint still bypasses that resolver and fails on private legacy keys whose context is supplied separately.
  • Affected clients can receive a failed download response for legitimate stored files.

apps/sim/app/api/files/download/route.ts

Important Files Changed

Filename Overview
apps/sim/lib/uploads/utils/file-utils.ts Adds trusted context resolution that prefers key-derived context and rejects public fallback for uninferrable keys.
apps/sim/lib/uploads/utils/file-utils.server.ts Updates server-side file URL resolution and storage downloads to use the trusted context resolver.
apps/sim/providers/file-attachments.server.ts Updates provider attachment access checks to use the trusted context resolver.
apps/sim/app/api/files/download/route.ts Still infers context directly from the key, so private legacy downloads can fail before URL generation.
apps/sim/app/api/files/parse/route.ts Removes an unused explicit-context parameter from cloud file parsing.

Reviews (4): Last reviewed commit: "fix" | Re-trigger Greptile

Comment thread apps/sim/lib/uploads/utils/file-utils.server.ts Outdated
Comment thread apps/sim/lib/uploads/utils/file-utils.server.ts Outdated
Comment thread apps/sim/providers/file-attachments.server.ts Outdated
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

Comment thread apps/sim/app/api/files/download/route.ts
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

Comment thread apps/sim/app/api/files/download/route.ts
@waleedlatif1 waleedlatif1 deleted the branch staging July 1, 2026 05:43
@waleedlatif1 waleedlatif1 reopened this Jul 1, 2026
}
// Derive context from the trusted key prefix, mirroring the serve route this URL
// delegates to, which re-derives context from the key and ignores any client-supplied value.
const storageContext = inferContextFromKey(key)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Legacy downloads still fail

This endpoint still calls inferContextFromKey(key) directly, even though the request contract still accepts context and isExecutionFile for files whose private storage context cannot be inferred from the key. For a stored legacy file such as legacy/ws/wf/ex/report.pdf with context: 'execution', this throws before access verification or URL creation. The client gets a failed download response instead of a URL for a file that the new trusted-context helper is meant to keep readable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants